package org.mozhu.mboot.core.web.sitemesh.tag;

import org.sitemesh.DecoratorSelector;
import org.sitemesh.config.PathBasedDecoratorSelector;
import org.sitemesh.content.Content;
import org.sitemesh.webapp.WebAppContext;

import java.io.IOException;
import java.util.Map;

/**
 * <pre>
 * <meta name="decorator" content="simple,pjax">
 *
 * Map<String, String> decoratorPaths = Maps.newHashMap();
 * decoratorPaths.put("simple", "/layout/simple_layout.ftl");
 * decoratorPaths.put("pjax", "/layout/pjax_layout.ftl");
 * MetaTagDecoratorSelector selector = new MetaTagDecoratorSelector(decoratorPaths);
 * </pre>
 */
public class MetaTagDecoratorSelector extends PathBasedDecoratorSelector<WebAppContext> implements DecoratorSelector<WebAppContext> {

    public static final String DECORATOR = "decorator";

    private Map<String, String> decoratorPaths;

    public MetaTagDecoratorSelector(Map<String, String> decoratorPaths) {
        this.decoratorPaths = decoratorPaths;
    }

    @Override
    public String[] selectDecoratorPaths(Content content, WebAppContext context) throws IOException {
        String decorator = context.getRequest().getParameter(DECORATOR);
        if (decorator == null) {
            decorator = context.getRequest().getHeader(DECORATOR);
        }
        if (decorator == null) {
            decorator = (String) context.getRequest().getAttribute(DECORATOR);
        }
        // Fetch <meta name=decorator> value.
        // The default HTML processor already extracts these into 'meta.NAME'
        // properties.
        if (decorator == null) {
            decorator = content.getExtractedProperties().getChild("meta").getChild(DECORATOR).getValue();
        }

        if (decorator != null) {
            // If present, return it.
            // Multiple chained decorators can be specified using commas.
            return toPath(decorator.split(","));
        } else {
            // Otherwise, fallback to the standard configuration.
            return super.selectDecoratorPaths(content, context);
        }
    }

    private String[] toPath(String[] decorators) {
        String[] paths = new String[decorators.length];
        for (int i = 0; i < decorators.length; i++) {
            String decorator = decorators[i];
            String path = decoratorPaths.get(decorator);
            paths[i] = path != null ? path : decorator;
        }
        return paths;
    }
}
